package com.yazi.mxz.job.quartz;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import javax.annotation.Resource;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.myframework.smhj.common.tool.DateUtil;
import com.myframework.smhj.hibernate.Searching;
import com.myframework.smhj.hibernate.Page;
import com.yazi.mxz.common.Config;
import com.yazi.mxz.common.entity.beans.Sms;
import com.yazi.mxz.common.entity.enums.SmsStatus;
import com.yazi.mxz.common.service.SmsService;
import com.yazi.mxz.job.common.MySetting;


public class SmsJob  extends MyJob {
	private static Logger log = LoggerFactory.getLogger(SmsJob.class);
	/**
	 * 累计发送失败次数，每次激活任务时重新累计。
	 */
	private static int error = 0;
	/**
	 * 任务状态，是否在执行
	 */
	private static boolean isWorking = false;
	
	@Resource
	SmsService smsService;	

	@Override
	public void run() {
		if (!MySetting.getSmsSwitch()) {
			log.warn("短信服务未开启");
			return;
		}
		isWorking = true;
		Sms smsFs = new Sms();
		smsFs.setStatus(SmsStatus.NEW.ordinal());
		smsFs.setAddTime(DateUtil.getTimeStamp() - MySetting.getSmsIndate() * 60000);
		Searching si = new Searching();
		si.setPageSize(Searching.MAX_PAGE_SIZE);
		Page<Sms> page = smsService.listByGtAddtime(smsFs, si);
		List<Sms> list = page.getList();
		boolean success = false;// 某个短信是否发送成功
		String result = null;
		for (Sms sms : list) {
			log.debug("发送短信：id={},mobile={},type={}", new Object[]{sms.getSmsId(), sms.getToMobile(), sms.getType()});
			success = true;
			try {
				result = sendSms(sms);
			} catch (Exception e) {
				log.error("短信发送失败", e);
				sms.setFail(sms.getFail() + 1);
				if (sms.getFail() > 3) { // TODO 等处理，限定尝试发送次数
					// 达到失败次数则取消
					sms.setStatus(SmsStatus.CANCEL.ordinal());
				}
				success = false;
				error++;
				// 失败达到限定次数就终止任务
				if (error == MySetting.getSmsError()) {
					break;
				}
			}
			if (success) {
				// 更新为“成功”状态
				sms.setStatus(SmsStatus.SUCCESS.ordinal());
			}
			sms.setResult(result);
			sms.setSendTime(DateUtil.getTimeStamp());
			smsService.merge(sms);
		}
		if (error < MySetting.getMailError() && si.getTotalPage() > si.getNowPage()) {
			 run();
			return;
		}
		isWorking = false;
		return;
	}

	@Override
	public void checkDoit(long timeStamp) {
		if (isWorking) return;
		error = 0;
		doit();
	}
	
	public void checkDoit() {
		checkDoit(0);
	}
	
	private String sendSms(Sms sms) throws InterruptedException, ExecutionException, ParseException, IOException {

		CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
		List <NameValuePair> params = new ArrayList<NameValuePair>();  
        String result = null;
		try {
			params.add(new BasicNameValuePair("mob", sms.getToMobile()));
	        params.add(new BasicNameValuePair("uid", MySetting.getSmsWeimiUid()));
	        params.add(new BasicNameValuePair("pas", MySetting.getSmsWeimiPas()));
	        params.add(new BasicNameValuePair("type", "json"));
	        
	        // 接口一模式
	        //params.add(new BasicNameValuePair("con", "【微米】您的验证码是：610912，3分钟内有效。如非您本人操作，可忽略本消息。"));
	        
	        // 接口二模式
	        params.add(new BasicNameValuePair("cid", MySetting.getSmsWeimiCids().split("\\|", -1)[sms.getType()]));
	        String[] ps = sms.getParams().split("\\|", -1);
	        for (int i = 0; i< ps.length; i++) {
	        	params.add(new BasicNameValuePair("p" + (i + 1), ps[i]));
	        }
	        
			httpclient.start();
			final HttpPost req = new HttpPost(MySetting.getSmsWeimiHost());
			req.setEntity(new UrlEncodedFormEntity(params,Config.getInstance().getEncoding()));
			Future<HttpResponse> future = httpclient.execute(req, null);
			HttpResponse res = future.get();
			if(res.getStatusLine().getStatusCode() == 200)  {  
                HttpEntity httpEntity = res.getEntity(); 
                result = EntityUtils.toString(httpEntity, Config.getInstance().getEncoding());
                log.debug("短信发送结果：id={}, result={}", sms.getSmsId(), result); 
            }
		} finally {
			httpclient.close();
		}
		return result;
	}
	
}
